package gestion.camping.dao.impl;

import gestion.camping.dao.GenericDAO;
import gestion.camping.dto.Personne;

import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.List;

/**
 * Permet la lecture, la modification, l'ajout ou la suppresion en base des enregistrement de la table Personne
 * 
 * @author Gombert Damien
 * @author Foucras Melanie
 * @author Germa Romain
 * 
 * @version 1.0
 */
public class PersonneDao extends GenericDAO<Personne>{

	public PersonneDao(Connection conn) {
		super(conn);
	}

	
	@Override
	public Personne create(Personne obj) {
		
		try {
			Statement smt = connect.createStatement();
			
			//On récupère le id qu'aura notre futur enregistrement
			//TODO transaction
			String rqt = "SELECT SEQ_PERSONNE.NEXTVAL FROM DUAL";
			ResultSet res = smt.executeQuery(rqt);
			res.next();			
			obj.setId(res.getInt(1));
			System.out.println(obj.getId());
			
			//On prépare la requête d'insertion
			rqt = String.format("INSERT INTO PERSONNE VALUES(%1$s, '%2$s', '%3$s', '%4$s', '%5$s','%6$s', '%7$s', '%8$s')",
										obj.getId(), obj.getNom(), obj.getDateNaissanceString(), obj.getPrenom(),
										obj.getAdresse(), obj.getCodePostal(), obj.getVille(), obj.getNumeroTelephone());
			
			//On trace la requête dans la console
			System.out.println(rqt);
			
			//ON effectue l'insertion en base de données		
			smt.executeUpdate(rqt);
			
			//On ferme la transaction
			smt.close();

									
		} catch (SQLException e) {
			gestionErreurSQL(e);
		}
		
		
		return obj;
	}

	@Override
	public boolean delete(Personne obj) {
		return false;
	}

	@Override
	public Personne update(Personne obj) {
				
		try {
			Statement smt = connect.createStatement();
			
			//On récupère le id qu'aura notre futur enregistrement
			//TODO Controler la date version
			
			//On prépare la requête de modification
			String rqt = String.format("UPDATE PERSONNE SET PERSONNE_NOM = '%1$s', " +
										"					PERSONNE_PRENOM = '%2$s'," +
										"					PERSONNE_ADRESSE = '%3$s'," +
										"					PERSONNE_CODE_POSTAL = '%4$s'," +
										"					PERSONNE_VILLE = '%5$s', " +
										"					PERSONNE_TELEPHONE = '%6$s'," +
										"					PERSONNE_DDN = '%7$s'" +
										"			WHERE PERSONNE_NUM = %8$s",
										obj.getNom().replaceAll("'", "''"),
										obj.getPrenom().replaceAll("'", "''"),
										obj.getAdresse().replaceAll("'", "''"),
										obj.getCodePostal().replaceAll("'", "''"), 
										obj.getVille().replaceAll("'", "''"),
										obj.getNumeroTelephone().replaceAll("'", "''"),
										obj.getDateNaissanceString(),
										obj.getId());
			
			//On trace la requête dans la console
			System.out.println(rqt);
			
			//ON effectue l'insertion en base de données		
			smt.executeUpdate(rqt);
			
			//On ferme la transaction
			smt.close();
									
		} catch (SQLException e) {
			gestionErreurSQL(e);
		}
		
		return obj;
	}

	@Override
	public Personne find(int id) {
		Personne dto = new Personne();
		
		try {
			
			Statement smt = connect.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE, ResultSet.CONCUR_READ_ONLY);
			
			String rqt = "SELECT * FROM PERSONNE P WHERE P.PERSONNE_NUM="+ id;
			
			//Execution de la requ�te
			ResultSet res = smt.executeQuery(rqt);		
			
			// si il y a des r�sultat, on se positionne sur le premier enregistrement
			if(res.first()){
				// Et on initialise le dto
				dto.setId(id);
				dto.setNom(res.getString("PERSONNE_NOM"));
				dto.setPrenom(res.getString("PERSONNE_PRENOM"));
				dto.setAdresse(res.getString("PERSONNE_ADRESSE"));
				dto.setCodePostal(res.getString("PERSONNE_CODE_POSTAL"));
				dto.setDateNaissance(res.getDate("PERSONNE_DDN"));
				dto.setVille(res.getString("PERSONNE_VILLE"));
				dto.setNumeroTelephone(res.getString("PERSONNE_TELEPHONE"));
			}
			
			//On ferme la transaction
			smt.close();
		} catch (SQLException e) {
			e.printStackTrace();
		}

		return dto;
	}
	
	/**
	 * Récupère l'ensemble des personnes
	 * 
	 * @return toutes les personnes présente dans la base 
	 */
	public List<Personne> findAllPersonne(){
		List<Personne> listPersonne = new ArrayList<Personne>();
		
		try {
			
			Statement smt = connect.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE, ResultSet.CONCUR_READ_ONLY);
			
			String rqt = "SELECT * FROM PERSONNE P";
			
			//Execution de la requ�te
			ResultSet res = smt.executeQuery(rqt);		
			
			//On crée un dtoPersonne temporaire
			Personne dto;
			
			// Tant qu'il y a des résultat
			while(res.next()){
				//on initialise le dto
				dto = new Personne();
				dto.setId(res.getLong("PERSONNE_NUM"));
				dto.setNom(res.getString("PERSONNE_NOM"));
				dto.setPrenom(res.getString("PERSONNE_PRENOM"));
				dto.setAdresse(res.getString("PERSONNE_ADRESSE"));
				dto.setCodePostal(res.getString("PERSONNE_CODE_POSTAL"));
				dto.setDateNaissance(res.getDate("PERSONNE_DDN"));
				dto.setVille(res.getString("PERSONNE_VILLE"));
				dto.setNumeroTelephone(res.getString("PERSONNE_TELEPHONE"));
				
				//Et on ajoute le dto à la liste
				listPersonne.add(dto);
			}
			
			//On ferme la transaction
			smt.close();
						
		} catch (SQLException e) {
			e.printStackTrace();
		}
		
		return listPersonne;
	}


	public List<Personne> findByNomPrenom(String nom, String prenom) {
		List<Personne> listPersonne = new ArrayList<Personne>();
		
		try {
			
			Statement smt = connect.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE, ResultSet.CONCUR_READ_ONLY);
			
			StringBuilder rqt = new StringBuilder("SELECT * FROM PERSONNE P ");
			boolean clause = false;
			if(nom != null && !nom.equals("")){
				rqt.append(" WHERE P.PERSONNE_NOM LIKE '%"+ nom +"%'");
				clause = true;
			}
			
			if(prenom != null && !prenom.equals("")){
				if(clause){
					rqt.append(" AND ");
				}else{
					rqt.append(" WHERE ");
				}
				
				rqt.append(" UPPER(P.PERSONNE_PRENOM) LIKE '%"+ prenom +"%'");
			}
			
			//On trace la requète dans la console
			System.out.println(rqt.toString());
						
			//Execution de la requ�te
			ResultSet res = smt.executeQuery(rqt.toString());	
			
			//On crée un dtoPersonne temporaire
			Personne dto;
			
			// Tant qu'il y a des résultat
			while(res.next()){
				//on initialise le dto
				dto = new Personne();
				dto.setId(res.getLong("PERSONNE_NUM"));
				dto.setNom(res.getString("PERSONNE_NOM"));
				dto.setPrenom(res.getString("PERSONNE_PRENOM"));
				dto.setAdresse(res.getString("PERSONNE_ADRESSE"));
				dto.setCodePostal(res.getString("PERSONNE_CODE_POSTAL"));
				dto.setDateNaissance(res.getDate("PERSONNE_DDN"));
				dto.setVille(res.getString("PERSONNE_VILLE"));
				dto.setNumeroTelephone(res.getString("PERSONNE_TELEPHONE"));
				
				//Et on ajoute le dto à la liste
				listPersonne.add(dto);
			}
			
			//On ferme la transaction
			smt.close();
						
		} catch (SQLException e) {
			e.printStackTrace();
		}
		
		return listPersonne;
	}


	
	
	
	public void unlock(Personne personne) {
		try {
			connect.commit();
			connect.setAutoCommit(true);
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}


	public boolean lock(Personne personne) {
		
		
		try {
			
			Statement smt = connect.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE, ResultSet.CONCUR_READ_ONLY);
			connect.setAutoCommit(false);
			
			String rqt = "SELECT * FROM PERSONNE P WHERE P.PERSONNE_NUM="+ personne.getId() + "  FOR UPDATE WAIT 2";
			
			//Execution de la requ�te
			smt.executeQuery(rqt);		
			
			//On ferme la transaction
			smt.close();
			
		} catch (SQLException e) {
			gestionErreurSQL(e);
			return false;
		}

		return true;
	}

	
}
